package com.ziq.base.service

import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.IBinder
import com.ziq.base.manager.WebSocketManager
import com.ziq.base.utils.LogUtil
import dagger.hilt.android.AndroidEntryPoint
import java.lang.ref.SoftReference
import java.lang.ref.WeakReference
import java.util.concurrent.ConcurrentLinkedQueue
import javax.inject.Inject

@AndroidEntryPoint
class LongLinkService : Service() {
    companion object {
        const val TAG = "LongLinkService"

        fun startZQPlayerService(context: Context) {
            val intent = Intent(context, LongLinkService::class.java)
            context.startService(intent)
        }

        fun stopZQPlayerService(context: Context) {
            val intent = Intent(context, LongLinkService::class.java)
            context.stopService(intent)
        }

        fun bindZQPlayerService(context: Context, serviceConnection: ServiceConnection) {
            //需要先启动服务 start service first，不然直接绑定不会立即回调onServiceConnected， 待 服务start后，统一回调所有之前 进行的绑定动作
            val intent = Intent(context, LongLinkService::class.java)
            context.bindService(intent, serviceConnection, 0)
        }

        fun unbindZQPlayerService(context: Context, serviceConnection: ServiceConnection) {
            //activity 绑定的时候  把ServiceConnection 给了 服务，serviceConnection 强引用了activity, 退出activity时 不解绑会 内存泄漏
            //不会调用  ServiceConnection.onServiceDisconnected  只有服务crash 或被kill 才调用
            context.unbindService(serviceConnection)
        }
    }

    private var mBind : ILongLinkServiceBind? = null
    @Inject
    lateinit var mWebSocketManager : WebSocketManager
    private val mListener: ConcurrentLinkedQueue<SoftReference<ILongLinkListener>> = ConcurrentLinkedQueue()

    override fun onCreate() {
        super.onCreate()
        mBind = ILongLinkServiceBind(this)
        mWebSocketManager.onMessageReceive = {
            val message = MessageProto()
            message.parseData(it)
            if(message.op == MessageProto.OpRaw){
                message.body?.let { body->
                    message.parseData(body)
                }
            }
            for (item in mListener){
                item.get()?.onReceive(it, message.body)
            }
        }
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        LogUtil.i(TAG, "onStartCommand")
        return START_NOT_STICKY
    }

    override fun onDestroy() {
        LogUtil.i(TAG, "onDestroy")
        super.onDestroy()
    }

    override fun onBind(intent: Intent?): IBinder? {
        return mBind
    }

    class ILongLinkServiceBind() : ILongLinkService.Stub() {

        private var mService: WeakReference<LongLinkService>? = null

        constructor(service: LongLinkService) :this(){
            mService = WeakReference(service)
        }

        override fun connect(info: ConnectInfo) {
            mService?.get()?.mWebSocketManager?.connect(info)
        }

        override fun disconnect() {
            mService?.get()?.mWebSocketManager?.disconnect()
        }

        override fun send(byteArray: ByteArray) {
            mService?.get()?.mWebSocketManager?.send(byteArray)
        }

        override fun registerListener(listener: ILongLinkListener) {
            mService?.get()?.mListener?.add(SoftReference(listener))
        }

        override fun unregisterListener(listener: ILongLinkListener) {
            mService?.get()?.mListener?.remove(SoftReference(listener))
        }

    }
}